﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AzukiMap.DataSource;
using Geotools.Geometries;
using AzukiMap.Map;
using System.Windows.Media.Imaging;
using AzukiMap.Tools.Logger;

namespace AzukiMap.Layer
{
    public class RasterLayer : Layer
    {
        protected double _bufferWidth;
        protected double _bufferHeight;
        protected RasterSource _dataSource;
        GeometryUtil _geoUtil;

        public double BufferWidth
        {
            get { return _bufferWidth; }
            set { _bufferWidth = value; }
        }

        public double BufferHeight
        {
            get { return _bufferHeight; }
            set { _bufferHeight = value; }
        }

        public RasterSource DataSource
        {
            get { return _dataSource; }
        }

        public GTPolygon MapExtent
        {
            get { return _maxExtent; }
        }

        public RasterLayer(RasterSource rasterDataSource, MapCanvas mapCanvas, string name) 
            : base(mapCanvas, rasterDataSource.DataType)
        {
            Init(rasterDataSource, name, rasterDataSource.MaxExtent);
        }

        public RasterLayer(RasterSource rasterDataSource, MapCanvas mapCanvas, string name, GTPolygon mapExtent) 
            : base(mapCanvas, rasterDataSource.DataType)
        {
            Init(rasterDataSource, name, mapExtent);
        }

        void Init(RasterSource rasterDataSource, string name, GTPolygon maxExtent)
        {
            _dataSource = rasterDataSource;
            _name = name;
            _maxExtent = maxExtent;
            _geoUtil = new GeometryUtil();
        }

        public override void Draw()
        {
            if (! HasExtent() || ! CheckMaxExtent() || !CheckScale())
            {
                Logger.Debug("WMSLayer.Draw(): Drawing was skipped.");
                return;
            }
            Image rasterImage = new Image();
            BitmapImage imageSource = new BitmapImage(_dataSource.ImageUri);
            GTPoint origin = GetImageOrigin();
            
            rasterImage.Source = imageSource;
            rasterImage.Width = GetImageWidth();
            rasterImage.Height = GetImageHeight();
            rasterImage.HorizontalAlignment = HorizontalAlignment.Right;
            rasterImage.VerticalAlignment = VerticalAlignment.Top;
            rasterImage.RenderTransform = GetImageTransform();

            rasterImage.SetValue(Canvas.LeftProperty, origin.X);
            rasterImage.SetValue(Canvas.TopProperty, origin.Y);
            
            _mapCanvas.Children.Add(rasterImage);
        }

        public override void Clear()
        {
            base.Clear();
            _mapCanvas.Children.Clear();
        }

        GTPoint GetImageOrigin()
        {
            GTCoordinate tlPoint = _geoUtil.GetExtentPoint(_maxExtent, ExtentOrder.TOP_LEFT);
            return _mapCanvas.GetPixPointFromGeo(tlPoint.X, tlPoint.Y);
        }

        double GetImageWidth()
        {
            //return _dataSource.Width * _mapCanvas.ScreenScale * (_dataSource.Dpi / AzukiMapSettings.DPI);
            double extentWidth = _geoUtil.GetExtentPolygonWidth(_dataSource.MaxExtent);
            return extentWidth / _mapCanvas.ScreenScale / GetDpiRatio();
        }

        double GetImageHeight()
        {
            double extentHeight = _geoUtil.GetExtentPolygonHeight(_dataSource.MaxExtent);
            return extentHeight / _mapCanvas.ScreenScale / GetDpiRatio();
        }

        double GetDpiRatio()
        {
            return 1.0; // (double)AzukiMapSettings.DPI / (double)_dataSource.Dpi;
        }

        TransformGroup GetImageTransform()
        {
            TransformGroup transGroup = new TransformGroup();
            TranslateTransform moveTransform = new TranslateTransform();
            ScaleTransform scaleTransform = new ScaleTransform();

            double geoWidth = _geoUtil.GetExtentPolygonWidth(_dataSource.MaxExtent);
            double geoHeight = _geoUtil.GetExtentPolygonHeight(_dataSource.MaxExtent);
            double imgOrgWidth = _dataSource.Width;
            double imgOrgHeight = _dataSource.Height;

            double geoAspectRatio = geoWidth / geoHeight;
            double imgAspectRatio = imgOrgWidth / imgOrgHeight;

            double scaleX = geoAspectRatio / imgAspectRatio;
            double moveX = GetImageWidth() * (( scaleX - 1 ) / 2) * -1;

            //scaleTransform.ScaleX = 1.243256417;
            scaleTransform.ScaleX = scaleX;
            //moveTransform.X = GetImageWidth() * (0.243256417 / 2) * -1;
            moveTransform.X = moveX;

            transGroup.Children.Add(scaleTransform);
            transGroup.Children.Add(moveTransform);

            return transGroup;
        }

        bool HasExtent()
        {
            return (! _maxExtent.IsEmpty());
        }
    }
}
